#include "JSegmentation.h"
#include "Segmentation.h"

/*
 * Class:     JSegmentation
 * Method:    segment
 * Signature: (IIIII[D[D[DDIII)I
 */

using namespace std;

JNIEXPORT jint JNICALL Java_JSegmentation_segment(JNIEnv *env, jclass jc, jint height, jint width, jint depth, 
	      jint numberOfImages, jint numberOfRegions, jshortArray images, jshortArray mask, jshortArray initialPoints,
		  jdouble smoothCost, jint iterations, jint graphIterations, jint logFlag){

	//Obtain images pointer
	jshort* imagesPtr   = env->GetShortArrayElements(images,0);

	//Obtain initialPoints pointer
	jshort* initialPointsPtr   = env->GetShortArrayElements(initialPoints,0);

	//Obtain mask pointer
	jshort* maskPtr   = env->GetShortArrayElements(mask,0);

	Segmentation *seg = new Segmentation(height, width, depth , numberOfImages, numberOfRegions, initialPointsPtr, imagesPtr);

	seg->setPrintFlag(logFlag);

	if (maskPtr[0] != (double) -1) //CODE TO FIND OUT IF THERE IS NOT MASK SETTED
	   seg->setMask(maskPtr);

	seg->expandRegions(iterations);

	seg->setSmoothFactor(smoothCost);

	if (smoothCost > 0)
		seg->expansion(graphIterations);

	seg->exportInitialPoints(initialPointsPtr);

	delete seg;

	env->ReleaseShortArrayElements(images, imagesPtr,0);
	env->ReleaseShortArrayElements(mask, maskPtr,0);
	env->ReleaseShortArrayElements(initialPoints, initialPointsPtr,0);
	return 0;
}

JNIEXPORT jint JNICALL Java_JSegmentation_analyze(JNIEnv *env, jclass jc, jint height, jint width, jint depth, jint numberOfImages, jint numberOfRegions, jshortArray images, jshortArray mask, jshortArray initialPoints, jdoubleArray means, jdoubleArray variances, jdoubleArray curtosis){

	//Obtain images pointer
	jshort* imagesPtr   = env->GetShortArrayElements(images,0);

	//Obtain initialPoints pointer
	jshort* initialPointsPtr   = env->GetShortArrayElements(initialPoints,0);

	//Obtain mask pointer
	jshort* maskPtr   = env->GetShortArrayElements(mask,0);

	//Obtain means pointer
	jdouble* meansPtr =  env->GetDoubleArrayElements(means,0);

	//Obtain variances pointer
	jdouble* variancesPtr =  env->GetDoubleArrayElements(variances,0);

	jdouble* curtosisPtr =  env->GetDoubleArrayElements(curtosis,0);

	Segmentation *seg = new Segmentation(height, width, depth , numberOfImages, numberOfRegions, initialPointsPtr, imagesPtr);

	if (maskPtr[0] != (double) -1) //CODE TO FIND OUT IF THERE IS NOT MASK SETTED
	   seg->setMask(maskPtr);

	
	double* regionMeans = new double[numberOfImages];
	double* regionVariances = new double[numberOfImages];
	double* regionCurtosis = new double[numberOfImages];

	for (int i=0; i < numberOfRegions; i++){
		seg->exportMean(i,regionMeans);
		seg->exportVariance(i,regionVariances);
		seg->getCurtosis(i,regionCurtosis);
		for (int j=0; j < numberOfImages; j++){
			meansPtr[j + numberOfImages*i] = regionMeans[j];
			variancesPtr[j + numberOfImages*i] = regionVariances[j];
			curtosisPtr[j + numberOfImages*i] = regionCurtosis[j];
		}

	}
	
	delete seg;

	env->ReleaseShortArrayElements(images, imagesPtr,0);
	env->ReleaseShortArrayElements(mask, maskPtr,0);
	env->ReleaseShortArrayElements(initialPoints, initialPointsPtr,0);
	
	env->ReleaseDoubleArrayElements(means, meansPtr,0);
	env->ReleaseDoubleArrayElements(variances, variancesPtr,0);
	env->ReleaseDoubleArrayElements(curtosis, curtosisPtr,0);
	return 0;
}

